package prototypes;

import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;

/**
 * 
 * The prototype server class is intended to be an early iteration of the
 * Operations Server. It will be used to experiment with approaches to handling
 * services and implementing the functionality of the Operations system
 * generally.
 * 
 * @author Matthew Johnstone <mjohnstone357@gmail.com>
 * 
 */
public class Server {

	/* The default port to listen on. */
	public static final int DEFAULT_PORT = 6890;

	/* The port number to listen on. */
	private int port;

	/* The output and error streams. */
	private PrintStream stdout;
	private PrintStream stderr;

	private NetworkMap map;
	private TaskQueue queue;

	public Server(int port, PrintStream stdout, PrintStream stderr) {
		this.port = port;
		this.stdout = stdout;
		this.stderr = stderr;
		// TODO Set up map and queue
		
	}

	public Server() {
		port = DEFAULT_PORT;
		stdout = System.out;
		stderr = System.err;
		// TODO Set up map and queue		
	}

	/**
	 * Runs an instance of the Operations Prototype Server.
	 * 
	 * @return an exit status code. Zero denotes successful execution, and any
	 *         positive value indicates an error.
	 * @throws IOException
	 *             if an I/O error occurs when opening the server socket.
	 */
	public int runServer() throws IOException {

		stdout.println("Starting Operations Prototype Server on port " + port
				+ ".");

		ServerSocket serverSocket = new ServerSocket(port);

		stdout.println("Listening for connections.");

		// TODO Produce a thread for each service

		while (true) {
			Socket client = serverSocket.accept();

			System.out
					.println("Server handing client connection to a new thread.");

			ConnectionHandler handler = new ConnectionHandler(client);

			Thread t = new Thread(handler);

			t.start();
		}

	}

	public static void main(String[] args) {
		Server s = new Server();

		int status = -1;

		try {
			status = s.runServer();
		} catch (IOException e) {
			e.printStackTrace();
		}

		System.out.println("Exited with status " + status + ".");

	}

}
